package com.xcc;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;


public class MinaServer {
    private static MinaServer minaServer;
    private IoAcceptor acceptor;

    private MinaServer() {
        acceptor = new NioSocketAcceptor();
        acceptor.getFilterChain().addLast("logger", new LoggingFilter());
        //acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        acceptor.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        acceptor.setHandler(new ServerHandle());
        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        try {
            acceptor.bind(new InetSocketAddress(10115));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //acceptor.dispose();
    }

    public synchronized static void start() {
        if (minaServer == null) {
            minaServer = new MinaServer();
        }
    }

    public synchronized static void stop() {
        if (minaServer == null) return;
        minaServer.stop_();
        minaServer = null;
    }

    public synchronized static boolean isRuning() {
        return minaServer != null;
    }

    private void stop_() {
        acceptor.dispose();
        acceptor = null;
    }

    public static class ServerHandle extends IoHandlerAdapter {
        private final List<IoSession> userList = new ArrayList<>();

        public void sessionCreated(IoSession session) throws Exception {
            System.out.println("User Login:" + session.getRemoteAddress());
            synchronized (userList) {
                userList.add(session);
                System.out.println("User Total:" + userList.size());
            }
        }

        public void sessionOpened(IoSession session) throws Exception {
        }

        public void messageReceived(IoSession session, Object message) throws Exception {
            if (message instanceof BaseMsg) {
                BaseMsg baseMsg = (BaseMsg) message;
                if (baseMsg.type == 0) {

                } else {
                    System.out.println(baseMsg.msg);
                }
            } else {
                String string = message.toString();
                System.out.println(string);
                List<IoSession> list;
                synchronized (userList) {
                    list = new ArrayList<>(userList);
                }
                for (int i = 0; i < list.size(); i++) {
                    IoSession ioSession = list.get(i);
                    if (ioSession == session) continue;
                    ioSession.write(string);
                }
            }
            /*BaseMsg baseMsg = new BaseMsg();
            baseMsg.type = 1;
            baseMsg.msg = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(System.currentTimeMillis());
            session.write(baseMsg);*/
        }

        public void messageSent(IoSession session, Object message) throws Exception {
        }

        public void sessionClosed(IoSession session) throws Exception {
            System.out.println("User exit:" + session.getRemoteAddress());
            synchronized (userList) {
                userList.remove(session);
                System.out.println("User Total:" + userList.size());
            }
        }
    }
}
